package netty;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.List;

/**
 * 功能: nettyserver 初始化相关的参数,是否开启调试日志，处理数据的handler
 *
 * @author helloworldyu
 * @date 2018/5/3
 */
public class NettyServerInitializer<C extends Channel> extends ChannelInitializer<C> implements ApplicationContextAware{
	private static final Logger logger = LoggerFactory.getLogger(NettyServerInitializer.class);


	/**
	 * spring 的 bean 信息
	 */
	private static ApplicationContext applicationContext;


	/**
	 * 重写以获取 spring 的 bean 信息
	 * @param applicationContext
	 * @throws BeansException
	 */
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		// The spring application context.
		NettyServerInitializer.applicationContext = applicationContext;
	}

	/**
	 * 根据beanName获取bean
	 */
	public static Object getBean(String beanName)
	{
		if (null == beanName)
		{
			return null;
		}
		return applicationContext.getBean(beanName);
	}


	/**
	 * netty 日志等级
	 */
	private LogLevel logLevel;
	/**
	 * 所有handler处理适配器
	 */
	private List<String> adapters;
	/**
	 * 空闲超时处理器
	 */
	private String idleStateHandler;

	/**
	 * 没有超时处理的版本
	 * @param logLevel
	 * @param adapters
	 */
	public NettyServerInitializer(LogLevel logLevel, List<String> adapters){
		this.logLevel = logLevel;
		this.adapters = adapters;
	}

	/**
	 * 有超时处理器的版本
	 * @param logLevel 日志等级
	 * @param idleStateHandler 超时处理器
	 * @param adapters  入站处理
	 */
	public NettyServerInitializer(LogLevel logLevel,
	                              String idleStateHandler,
	                              List<String> adapters) {
		this.logLevel = logLevel;
		this.adapters = adapters;
		this.idleStateHandler = idleStateHandler;
	}


	@Override
	protected void initChannel(C ch){
		ChannelPipeline pipeline = ch.pipeline();

		//设置日志
		pipeline.addLast("logging",new LoggingHandler(this.logLevel));
		//添加超时处理器
		if( null != this.idleStateHandler ){
			IdleStateHandler handler = (IdleStateHandler)getBean(this.idleStateHandler);
			pipeline.addLast(handler);
		}
		//添加处理器
		this.adapters.stream().forEach(c->{
			//通过初始化传进来的 bean 名字来初始化获取 bean
			ChannelHandlerAdapter handler = (ChannelHandlerAdapter)getBean(c);
			pipeline.addLast(handler);
		});

		logger.debug("新客户端链接:{}",this.toString());
	}

	@Override
	public String toString() {
		return "\n========================================================================\n"+
				"NettyTcpServerInitializer\n" +
				"logLevel=" + logLevel + "\n"+
				"adapters=" + adapters + "\n"+
				"idleStateHandlers=" + idleStateHandler +"\n"+
				"========================================================================\n"
				;
	}
}